//    Copyright (C) Kherty.  All rights reserved.
using System;

namespace OpenLS.Spreadsheet.StandardAddIn.Statistics
{
    internal abstract class IntegerDistribution : Distribution
    {
        public override double CumulativeProbability(double x)
        {
            return CumulativeProbability((int) Math.Floor(x));
        }

        public abstract double CumulativeProbability(int x);

        public double Probability(double x)
        {
            double fl = Math.Floor(x);
            if (fl == x)
            {
                return Probability((int) x);
            }
            else
            {
                return 0;
            }
        }


        public virtual int InverseCumulativeProbability(double probability)
        {
            CheckValidProperty(probability);
            int x0 = DomainLowerBound(probability);
            int x1 = DomainUpperBound(probability);
            double pm;
            while (x0 < x1)
            {
                int xm = x0 + (x1 - x0)/2;
                pm = CumulativeProbability(xm);
                if (pm > probability)
                {
                    if (xm == x1)
                    {
                        x1--;
                    }
                    else
                    {
                        x1 = xm;
                    }
                }
                else
                {
                    if (xm == x0)
                    {
                        ++x0;
                    }
                    else
                    {
                        x0 = xm;
                    }
                }
            }
            pm = CumulativeProbability(x0);
            while (pm > probability)
            {
                x0--;
                pm = CumulativeProbability(x0);
            }
            return x0;
        }

        protected abstract int DomainLowerBound(double p);

        protected abstract int DomainUpperBound(double p);

        public abstract double Probability(int x);
    }
}